%{
#include "core/json/json.h"
%}

%union 	{
		long d;
		double f;
		std::string* s;
		u915::json::NodePtr node;
		};

%token TRUE FALSE NIL 
%token<s> STRING
%token<d> INTEGER
%type<node> any  nil boolean integer string array object map_items array_items
%%

any: nil { $$=$1;} | boolean  { $$=$1;}  | string  { $$=$1;} | array  { $$=$1;}  | object  { $$=$1;}  | integer { $$=$1;} ;
nil: NIL { $$= new u915::json::NilNode();}
	;
boolean: TRUE { $$= new u915::json::BoolNode(true);}
		|  FALSE { $$= new u915::json::BoolNode(false);}
		;
string:	STRING {$$=new  u915::json::StringNode(*($1)); delete $1;}
	;

integer: INTEGER { $$=new  u915::json::IntNode($1); }
array: '[' ']' { $$= new ArrayNode();} | '[' array_items ']' { $$=$2;};
array_items:
	any {$$=new ArrayNode(); ((ArrayNode*)$$)->push_back($1);}
	| array_items ',' any {$$=$1; ((ArrayNode*)$$)->push_back($3);}
	;

object: '{' '}' { $$= new ObjectNode();}
	| '{' map_items '}' { $$= $2;}
	;

map_items: STRING ':' any
	{
	$$=new ObjectNode();
	((ObjectNode*)($$))->put((*$1),$3);
	delete $1;
	}
	| map_items ',' STRING ':' any
	{
	((ObjectNode*)($$))=$1;
	((ObjectNode*)($$))->put((*$3),$5);
	delete $3;
	}
	;	


%%